﻿using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.UIElements;

namespace DA.AnimGraph.Editor {
    public class SearchList : VisualElement {

        private List<ISearchListItem> source;
        private bool isSearching;

        private TextField searchField;
        private Button clearSearchButton;
        private ListView listView;

        public List<ISearchListItem> itemsSource {
            set {
                source = value;
                listView.itemsSource = source;
            }
        }

        public SearchList() {
            isSearching = false;

            var searchContainer = new VisualElement() {
                name = "searchContainer",
                style = {
                    flexDirection = FlexDirection.Row,
                    minHeight = 25,
                }
            };
            searchField = new TextField("Search") {
                style = {
                    flexGrow = 1,
                }
            };
            clearSearchButton = new Button(ClearSearch) {
                text = "X"
            };
            searchField.RegisterCallback<ChangeEvent<string>>(evt => Search(evt.newValue));
            searchContainer.Add(searchField);
            searchContainer.Add(clearSearchButton);
            Add(searchContainer);

            listView = new ListView() {
                name = "search-list-view",
                reorderable = false,
                selectionType = SelectionType.Single,
                fixedItemHeight = 40, // 初始22
                // showAlternatingRowBackgrounds = AlternatingRowBackground.All,
                showBorder = true,
                style = {
                    marginTop = 10,
                }
            };
            listView.bindItem = BindItem;
            listView.makeItem = () => new SearchListEntry();
            Add(listView);
        }

        private void Search(string text) {
            if (!string.IsNullOrEmpty(text)) {
                string searchStr = text.ToLower();
                var newList = source.Where(n => {
                    var path = n.GetPath().ToLower();
                    var result = path.Contains(searchStr);
                    return result;
                }).ToList();
                listView.itemsSource = newList;
                listView.Rebuild();
                isSearching = true;
            } else if (isSearching) {
                ClearSearch();
            }
        }

        void ClearSearch() {
            searchField.value = null;
            listView.itemsSource = source;
            listView.Rebuild();
            isSearching = false;
        }

        private void BindItem(VisualElement item, int index) {
            if (item is SearchListEntry entry) {
                entry.SetData(listView.itemsSource[index] as ISearchListItem);
            }
        }
    }

    public class SearchListEntry : VisualElement {

        public static Color highLightColor = new Color(0.4f, 1f, 0.6f);
        public static Color warningColor = Color.yellow;
        public static Color weakColor = new Color(0.5f, 0.5f, 0.5f);

        private ISearchListItem data;

        Label nameLabel;
        Label pathLabel;
        private VisualElement actionContainer;

        public SearchListEntry() {
            style.flexDirection = FlexDirection.Column;
            var container1 = new VisualElement() {
                style = {
                    flexDirection = FlexDirection.Row,
                    // flexGrow = 1,
                }
            };
            var container2 = new VisualElement() {
                style = {
                    flexDirection = FlexDirection.Row,
                    // flexGrow = 1,
                }
            };
            Add(container1);
            Add(container2);

            nameLabel = new Label() {
                style = {
                    flexGrow = 1,
                    unityTextAlign = TextAnchor.MiddleLeft,
                    color = highLightColor,
                }
            };
            pathLabel = new Label() {
                style = {
                    flexGrow = 1,
                    unityTextAlign = TextAnchor.MiddleLeft,
                    color = weakColor,
                }
            };

            actionContainer = new VisualElement() {
                name = "actionContainer",
                style = {
                    flexDirection = FlexDirection.Row,
                }
            };
            container1.Add(nameLabel);
            container1.Add(actionContainer);
            container2.Add(pathLabel);
        }

        public void SetData(ISearchListItem data) {
            actionContainer.Clear();
            this.data = data;
            nameLabel.text = data.GetName();
            pathLabel.text = data.GetPath();
            var actions = data.GetActions();
            foreach (var action in actions) {
                var b = new Button() {
                    text = action.Item1,
                };
                b.clicked += () => action.Item2(this.data);
                actionContainer.Add(b);
            }
        }
    }

    public interface ISearchListItem {
        string GetName();
        string GetPath();
        (string, Action<ISearchListItem>)[] GetActions();
    }

}